using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.Net.Sockets;
using System.Web;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using Ltf.Remoting.Server;
using System.Diagnostics;
using Ltf.Remoting.Settings;
using Ltf.Remoting.RemoteEvents;
using System.Xml.Serialization;
using Ltf.Remoting;
using System.IO;
using System.Threading;
using Ltf.MonitorLizard.Forms;
using Ltf.Remoting.TeamFoundation;
using Ltf.Diffs;
using Ltf.Remoting.Commands;
using Lizard.Remoting.Settings;

namespace Ltf.MonitorLizard
{
	public partial class Lizard : Form
	{

		[System.Runtime.InteropServices.DllImport("imagehlp.dll")]
		public static extern int MapFileAndCheckSumA(string fileName, ref int headerSum, ref int checkSum);

		private const string lizardTFVersion = "0.3.0";

		private static string lastPath;

		private NotifyIcon notifyIcon;

		private FileSystemWatcher fsWatcher;


		public Lizard(RemoteEventRaiser remoteEventRaiser) : this(remoteEventRaiser, false)
		{		}
		
		public Lizard(RemoteEventRaiser remoteEventRaiser, bool noShow)
		{
			InitializeComponent();
			if (!noShow)
			{
				notifyIcon = new NotifyIcon();
				notifyIcon.Text = "lizardMonitor";
				notifyIcon.Visible = true;
				notifyIcon.Icon = new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream("Ltf.MonitorLizard.Lizard.ico"));
				notifyIcon.Click += new EventHandler(notifyIcon_Click);
			}
			remoteEventRaiser.OpenMonitorForm += new LizardEventHandler(remoteEventRaiser_OpenMonitorForm);
			remoteEventRaiser.MessageBox += new LizardEventHandler(remoteEventRaiser_MessageBox);
			try
			{
				TFSettings tfs = (TFSettings)SettingsFactory.LoadSettings("Server", typeof(TFSettings));
				txtUsername.Text = tfs.User;
				txtPassword.Text = tfs.Password;
				txtServerUrl.Text = tfs.Server;
				txtMetaFolderName.Text = tfs.LtfMetaFolderName;
				txtIncludedDrives.Text = tfs.IncludedDrives;
				txtExcludedFolders.Text = tfs.Excludedfolders;
				txtExcludedFiles.Text = tfs.Excludedfiles;
				txtEditorPath.Text = tfs.EditTool;
				txtTempPath.Text = tfs.TempPath;
				ckbAutoCheckOut.Checked = tfs.AutoCheckoutChangedFiles;

				Microsoft.Win32.Registry.SetValue("HKEY_CURRENT_USER\\Software\\LizardTF", "MetaDataFolder", tfs.LtfMetaFolderName, Microsoft.Win32.RegistryValueKind.String);
				Microsoft.Win32.Registry.SetValue("HKEY_CURRENT_USER\\Software\\LizardTF", "TempFolder", tfs.TempPath, Microsoft.Win32.RegistryValueKind.String);

				txtDefaultWorkingPath.Text = tfs.DefaultWorkingPath;

				TFServerConnection connection = new TFServerConnection(tfs);
				ServerConnections.CreateConnectionsFromSettings(tfs);

				foreach (TFSecondarySettings tfsettings in tfs.AlternativeServerSettings)
				{
					tfsettings.PrimarySettings = tfs;
					CreateServerTabPage(tfsettings);
				}
				tabControl1.SelectedTab = tabControl1.TabPages[0];
				tabControl1.TabPages[0].Focus();
				if (tfs.AutoCheckoutChangedFiles && Directory.Exists(txtDefaultWorkingPath.Text))
				{
					CreateFileSystemWatcher();
				}
			}
			catch
			{

			}
			//ShowIntallationLabels();
			//TcpServer server = new TcpServer();
			//server.Start();
			if (!noShow)
			{
				LizardExplorer lizardExplorer = new LizardExplorer();
				lizardExplorer.Show();
			}
		}

		private void CreateFileSystemWatcher()
		{
			fsWatcher = new FileSystemWatcher();
			fsWatcher.Path = txtDefaultWorkingPath.Text;
			fsWatcher.Filter = "";
			fsWatcher.IncludeSubdirectories = true;
			fsWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
			fsWatcher.Changed += new FileSystemEventHandler(fsWatcher_Changed);
			fsWatcher.Created += new FileSystemEventHandler(fsWatcher_Created);
			fsWatcher.EnableRaisingEvents = true;
		}

		void fsWatcher_Created(object sender, FileSystemEventArgs e)
		{
			if (Path.GetFileName(Path.GetDirectoryName(e.FullPath)) == ServerConnections.DefaultConnection.Settings.LtfMetaFolderName)
				return;


			return;
		}

		void fsWatcher_Changed(object sender, FileSystemEventArgs e)
		{
			if (Path.GetFileName(Path.GetDirectoryName(e.FullPath)) == ServerConnections.DefaultConnection.Settings.LtfMetaFolderName)
				return;
			ServerFunctions sf = new ServerFunctions();
			GenerateOverlayInfo goi = new GenerateOverlayInfo(ServerConnections.GetConnectionForPath(e.FullPath));
			LizardFileInfo lfi = goi.GetFileInfoForPath(e.FullPath, false);

			LizardFileInfo newLfi = goi.GetFileInfoForPath(e.FullPath, true);


			if (lfi != null && (lfi.OverlayType == LizardOverLayStatus.CheckedInWritable || lfi.OverlayType == LizardOverLayStatus.ReadOnly))
			{
				try
				{
					sf.CheckOut(e.FullPath);
				}
				catch (Exception ex)
				{
					MessageBox.Show("Oops! " + ex.Message);
				}
			}
			else if (lfi != null && (lfi.OverlayType == LizardOverLayStatus.Locked && newLfi.OverlayType != LizardOverLayStatus.Locked))
			{
				ServiceWarning sw = new ServiceWarning(ShowServiceWarning);
				sw.BeginInvoke("Auto Checkout Failed",
					string.Format("You have made changes to a file, '{0}',\r\n that can not be checked out as another user, {1}, has a lock on it.", e.FullPath, lfi.LockOwner),
					null, null);
			}
		}

		private delegate void ServiceWarning(string caption, string message);

		private void ShowServiceWarning(string caption, string message)
		{
			MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning,
				MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
		}

		void remoteEventRaiser_MessageBox(object sender, LizardEventArgs lizardEventArgs)
		{
			this.Invoke(new LizardEventHandler(LaunchMessageBoxStart), new object[] { sender, lizardEventArgs });
		}

		void remoteEventRaiser_OpenMonitorForm(object sender, LizardEventArgs lizardEventArgs)
		{
			this.Invoke(new LizardEventHandler(LaunchOpenMonitorForm), new object[] { sender, lizardEventArgs });
		}

		void LaunchOpenMonitorForm(object sender, LizardEventArgs lizardEventArgs)
		{
			//		File.WriteAllText(ServerConnections.DefaultConnection.Settings.TempPath + "\\OnOpenMonitorForm.txt", string.Format("Type:{0} Paths:{1}", lizardEventArgs.FormType.ToString(), lizardEventArgs.PathList));
			try
			{
				if (lizardEventArgs.FormType == FormTypes.ProgressIndicator && typeof(ProgressEventArgs).IsAssignableFrom(lizardEventArgs.GetType()))
				{
					ProgressEventArgs pea = (ProgressEventArgs)lizardEventArgs;
					ProgressIndicator pi = new ProgressIndicator(pea.Title, pea.MainLabelText, pea.MaxProgress, pea.ProgressIncrement, pea.AllowCancel);
					pea.IncrementHandler = pi.IncrementHandler;
					pi.Show();
					pi.BringToFront();
					pi.Activate();
				}
				else if (LtfForms.ContainsKey(lizardEventArgs.FormType))
				{
					FormTypeConstructor ftc = LtfForms[lizardEventArgs.FormType];
					Form f = ftc.GetNewInstance(lizardEventArgs.Paths, lizardEventArgs);
					f.Show();
					f.BringToFront();
					f.Activate();
				}
			}
			catch (Exception ex)
			{
				this.BringToFront();
				ParameterizedThreadStart pts = new ParameterizedThreadStart(StartMessageBox);
				Thread t = new Thread(pts);
				string msg = string.Format("Failed to run lizard operation with exception:{0}\r\nat:\r\n{1}", ex.Message, ex.StackTrace);
				if (ex.InnerException != null)
					msg += string.Format("\r\nInnerException:{0}\r\nInner Trace:\r\n{1}", ex.InnerException.Message, ex.InnerException.StackTrace);
				t.Start(new LizardEventArgs(msg));
			}
		}

		void LaunchMessageBoxStart(object sender, LizardEventArgs lizardEventArgs)
		{
			this.BringToFront();
			ParameterizedThreadStart pts = new ParameterizedThreadStart(StartMessageBox);
			Thread t = new Thread(pts);
			t.Start(lizardEventArgs);
		}


		void StartMessageBox(object parameter)
		{
			LizardEventArgs lizardEventArgs = (LizardEventArgs)parameter;

			MessageBox.Show(lizardEventArgs.PathList, "LizardTF", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
		}

		void notifyIcon_Click(object sender, EventArgs e)
		{
			bool isPathValid = Directory.Exists(txtDefaultWorkingPath.Text);
			workItemsToolStripMenuItem.Enabled = isPathValid;
			repositoryBrowserToolStripMenuItem.Enabled = isPathValid;
			labelsToolStripMenuItem.Enabled = isPathValid;
			cmsTrayMenu.Show(MousePosition);
		}

		private void ShowHideSettings()
		{
			if (WindowState == FormWindowState.Minimized)
			{
				Show();
				WindowState = FormWindowState.Normal;
			}
			else
			{
				WindowState = FormWindowState.Minimized;
			}
		}

		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);
			if (WindowState == FormWindowState.Minimized)
			{
				Hide();
			}
		}




		/// <summary>
		/// Handles the Click event of the btnKillExp control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
		private void btnKillExp_Click(object sender, EventArgs e)
		{

			System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName("MonitorLizard");

			Process p = new Process();

			ProcessStartInfo taskKill = new ProcessStartInfo("taskkill", "/F /IM explorer.exe");
			taskKill.WindowStyle = ProcessWindowStyle.Hidden;
			p.StartInfo = taskKill;

			p.Start();
		}

		private void btnStartExp_Click(object sender, EventArgs e)
		{
			Process p = new Process();
			string winDir = System.Environment.GetEnvironmentVariable("windir");

			string explorer = Path.Combine(winDir, "explorer.exe");

			p.StartInfo.FileName = explorer;
			p.Start();
		}

		private void btnTestAndSave_Click(object sender, EventArgs e)
		{
			Ltf.Remoting.Settings.TFSettings tfs = ServerConnections.DefaultConnection.Settings;
			tfs.User = txtUsername.Text;
			tfs.Password = txtPassword.Text;
			tfs.Server = txtServerUrl.Text;
			tfs.LtfMetaFolderName = txtMetaFolderName.Text;
			tfs.IncludedDrives = txtIncludedDrives.Text;
			tfs.Excludedfolders = txtExcludedFolders.Text;
			tfs.Excludedfiles = txtExcludedFiles.Text;
			tfs.EditTool = txtEditorPath.Text;
			tfs.TempPath = txtTempPath.Text;
			tfs.DefaultWorkingPath = txtDefaultWorkingPath.Text;
			tfs.AutoCheckoutChangedFiles = ckbAutoCheckOut.Checked;

			try
			{
				Ltf.Remoting.Settings.SettingsFactory.SaveSettings("Server", tfs);

				ServerConnections.CreateConnectionsFromSettings(tfs);

				VersionControlServer vcServer = ServerConnections.DefaultConnection.VersionControlServer;

				TeamProject[] projects = vcServer.GetAllTeamProjects(true);
				List<string> projectNames = new List<string>();
				foreach (TeamProject tp in projects)
					projectNames.Add(tp.Name);
				MessageBox.Show("Settings founds the following team projects :" + string.Join(", ", projectNames.ToArray()), "Settings Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);

				Microsoft.Win32.Registry.SetValue("HKEY_CURRENT_USER\\Software\\LizardTF", "MetaDataFolder", txtMetaFolderName.Text, Microsoft.Win32.RegistryValueKind.String);
				Microsoft.Win32.Registry.SetValue("HKEY_CURRENT_USER\\Software\\LizardTF", "TempFolder", txtTempPath.Text, Microsoft.Win32.RegistryValueKind.String);

				if (tfs.AutoCheckoutChangedFiles && Directory.Exists(txtDefaultWorkingPath.Text))
				{
					CreateFileSystemWatcher();
				}

			}
			catch (Exception ex)
			{
				MessageBox.Show("Settings failed test with the error :" + ex.Message, "Settings Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void btnProjectBrowser_Click(object sender, EventArgs e)
		{
			Forms.LizardReview undoPending = new Forms.LizardReview(new string[] { "C:\\TFSProjects\\Lizard" }, new LizardEventArgs(""));
			undoPending.Show();
			undoPending.BringToFront();
		}


		private Dictionary<FormTypes, FormTypeConstructor> ltfForms;

		internal Dictionary<FormTypes, FormTypeConstructor> LtfForms
		{
			get
			{
				if (ltfForms == null)
				{
					ltfForms = new Dictionary<FormTypes, FormTypeConstructor>();
					foreach (Type t in this.GetType().Assembly.GetTypes())
					{
						object[] cas = t.GetCustomAttributes(false);
						foreach (object ca in cas)
						{
							if (typeof(FormTypeAttribute).IsAssignableFrom(ca.GetType()))
							{
								FormTypeAttribute fta = (FormTypeAttribute)ca;
								ltfForms.Add(fta.FormType, new FormTypeConstructor(t));
							}
						}

					}
				}
				return ltfForms;
			}

		}

		private void btnReg64_Click(object sender, EventArgs e)
		{
			RegisterExtensionDll(false);

		}

		private void RegisterExtensionDll(bool unregister)
		{
			string winDir = System.Environment.GetEnvironmentVariable("windir");

			string reg32 = Path.Combine(winDir, "System32\\RegSvr32.exe");
			string reg64 = string.Empty;

			bool x64 = IsX64();

			if (x64)
			{
				reg64 = Path.Combine(winDir, "System32\\RegSvr32.exe");
				reg32 = Path.Combine(winDir, "SysWOW64\\RegSvr32.exe");
			}

			string shellExt32;
			string shellExt64 = string.Empty; ;

			string asmFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);

			if (x64)
				shellExt64 = Path.Combine(asmFolder, "x64\\CLizardShExt.dll");

			shellExt32 = Path.Combine(asmFolder, "CLizardShExt.dll");

			if (!File.Exists(reg32))
			{
				MessageBox.Show("Can not find 32 bit regsvr32.exe registration utility at location :\r\n" + reg32, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			if (!File.Exists(reg64) && x64)
			{
				MessageBox.Show("Can not find 64 bit regsvr32.exe registration utility at location :\r\n" + reg64, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			if (!File.Exists(shellExt32))
			{
				MessageBox.Show("Can not find LizardTF shell extention dll at location :\r\n" + shellExt32, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}

			if (x64 && !File.Exists(shellExt64))
			{
				MessageBox.Show("Can not find LizardTF shell extention dll at location :\r\n" + shellExt64, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}


			Process p = new Process();

			ProcessStartInfo regSvr32 = new ProcessStartInfo(reg32, (unregister ? "/u " : "") + "\"" + shellExt32 + "\"");
			regSvr32.WindowStyle = ProcessWindowStyle.Hidden;
			regSvr32.UseShellExecute = false;
			p.StartInfo = regSvr32;

			p.Start();

			if (x64)
			{
				ProcessStartInfo regSvr32x64 = new ProcessStartInfo(reg64, (unregister ? "/u " : "") + "\"" + shellExt64 + "\"");
				regSvr32x64.WindowStyle = ProcessWindowStyle.Hidden;
				regSvr32x64.UseShellExecute = false;
				p.StartInfo = regSvr32x64;

				p.Start();
			}

			if (!unregister)
			{
				Microsoft.Win32.Registry.SetValue("HKEY_LOCAL_MACHINE\\Software\\LizardTF", "Version", lizardTFVersion);
			}
			else
			{
				Microsoft.Win32.Registry.SetValue("HKEY_LOCAL_MACHINE\\Software\\LizardTF", "Version", "None");
			}

			ShowIntallationLabels();
		}


		private void InstallTortoiseOverlays()
		{
			string winDir = System.Environment.GetEnvironmentVariable("windir");

			string wowDir = Path.Combine(winDir, "SysWOW64");

			bool x64 = Directory.Exists(wowDir);

			string to = string.Empty;

			string asmFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);

			if (x64)
				to = Path.Combine(asmFolder, "TortoiseOverlays-1.0.4.11886-x64.msi.");
			else
				to = Path.Combine(asmFolder, "TortoiseOverlays-1.0.4.11886-win32.msi.");


			if (!File.Exists(to))
			{
				MessageBox.Show("Can not find the Tortoise Overlays utility at location :\r\n" + to, "File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}


			Process p = new Process();

			ProcessStartInfo regSvr32 = new ProcessStartInfo(to);
			regSvr32.WindowStyle = ProcessWindowStyle.Normal;
			regSvr32.UseShellExecute = true;
			p.StartInfo = regSvr32;

			p.Start();

			ShowIntallationLabels();

		}

		private void btnUnregx64_Click(object sender, EventArgs e)
		{
			RegisterExtensionDll(true);
		}



		private void btnDiffTest_Click(object sender, EventArgs e)
		{
			ThreeWayDiff twd = new ThreeWayDiff();
			twd.CompareSideBySide("c:\\a", "c:\\b", "c:\\c", true, true);

			twd.Show();

			string s = string.Empty;

		}

		private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ShowHideSettings();
		}

		private void label1_Click(object sender, EventArgs e)
		{

		}

		private void textBox1_TextChanged(object sender, EventArgs e)
		{

		}

		private void repositoryBrowserToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string path = txtDefaultWorkingPath.Text;
			Workspace workspace = ServerConnections.GetConnectionForPath(path).GetWorkspace(path);
			if (workspace != null)
			{
				TFProjectBrowser tfpb = new TFProjectBrowser(path, ItemType.Any, workspace, true);
				tfpb.Show();
			}
			else
			{
				MessageBox.Show("Please check the default working path in the settings.", "No Valid Workspace for Working Path");
			}
		}

		private void workItemsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string path = txtDefaultWorkingPath.Text;
			TFServerConnection connection = ServerConnections.GetConnectionForPath(path);
			Workspace workspace = connection.GetWorkspace(path);
			if (workspace != null)
			{
				WorkItemQueries wiq = new WorkItemQueries(connection, workspace, path);
				wiq.Show();
			}
			else
			{
				MessageBox.Show("Please check the default working path in the settings.", "No Valid Workspace for Working Path");
			}
		}

		private void labelsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string path = txtDefaultWorkingPath.Text;
			TFServerConnection connection = ServerConnections.GetConnectionForPath(path);
			Workspace workspace = connection.GetWorkspace(path);
			if (workspace != null)
			{
				Labels lbls = new Labels(path);
				lbls.Show();
			}
			else
			{
				MessageBox.Show("Please check the default working path in the settings.", "No Valid Workspace for Working Path");
			}
		}

		private void button2_Click(object sender, EventArgs e)
		{
			CreateServerTabPage(null);
		}


		private void CreateServerTabPage(TFSettings settings)
		{
			TabPage tp = new TabPage();
			tp.Name = "tbPage" + tabControl1.TabPages.Count.ToString();
			tp.Text = "Server " + tabControl1.TabPages.Count.ToString();
			TabPage installPage = tabControl1.TabPages[tabControl1.TabPages.Count - 1];
			tabControl1.TabPages.Remove(installPage);
			tabControl1.TabPages.Add(tp);
			tabControl1.TabPages.Add(installPage);
			LizardSettings ls;
			if (settings == null)
				ls = new LizardSettings(tp, ServerConnections.DefaultConnection.Settings, true);
			else
				ls = new LizardSettings(tp, settings as TFSecondarySettings);

			ls.NewSettings += new EventHandler(ls_NewSettings);
			ls.RemoveServer += new EventHandler(ls_RemoveServer);

			tp.Controls.Add(ls);
			tabControl1.SelectedTab = tp;
			tp.Focus();
		}

	
		void ls_RemoveServer(object sender, EventArgs e)
		{
			DialogResult dr = MessageBox.Show("This will permanently remove any settings configured for this server. Do you wish to continue?",
				"Remove Server Settings", MessageBoxButtons.OKCancel);
			if (dr == DialogResult.OK)
			{
				LizardSettingsEventArgs lsea = (LizardSettingsEventArgs)e;
				tabControl1.TabPages.Remove(lsea.Page);
			}
		}

		void ls_NewSettings(object sender, EventArgs e)
		{
			LizardSettingsEventArgs lsea = (LizardSettingsEventArgs)e;
			if (!ServerConnections.DefaultConnection.Settings.AlternativeServerSettings.Contains(lsea.Settings))
				ServerConnections.DefaultConnection.Settings.AlternativeServerSettings.Add(lsea.Settings);

			Ltf.Remoting.Settings.SettingsFactory.SaveSettings("Server", ServerConnections.DefaultConnection.Settings);

		}

		private void label7_Click(object sender, EventArgs e)
		{

		}

		private void btnMetaFolder_Click(object sender, EventArgs e)
		{
			GetFolderPath(txtMetaFolderName, "Select a folder to store the LizardTF cache for the Team Foundation repository.", true);
		}

		private void GetFolderPath(TextBox txtFolderBox, string description, bool hasNewButton)
		{
			FolderBrowserDialog fbd = new FolderBrowserDialog();
			fbd.Description = description;
			fbd.SelectedPath = txtFolderBox.Text;

			fbd.ShowNewFolderButton = hasNewButton;

			if (fbd.ShowDialog() == DialogResult.OK)
				txtFolderBox.Text = fbd.SelectedPath;
		}

		private void GetExistingFilePath(TextBox txtFileNameBox)
		{
			OpenFileDialog ofd = new OpenFileDialog();
			ofd.FileName = txtFileNameBox.Text;

			if (ofd.ShowDialog() == DialogResult.OK)
				txtFileNameBox.Text = ofd.FileName;
		}

		private void btnEditorPath_Click(object sender, EventArgs e)
		{
			GetExistingFilePath(txtEditorPath);
		}

		private void btnTempPath_Click(object sender, EventArgs e)
		{
			GetFolderPath(txtTempPath, "Select a folder for LizardTF temporary files.", true);
		}


		private void btnWorkingPath_Click(object sender, EventArgs e)
		{
			GetFolderPath(txtDefaultWorkingPath, "Select a folder which LizardTF will use as the default workspace for system tray icon tools.", false);
		}

		private void btnInstallTortoiseOverlays_Click(object sender, EventArgs e)
		{
			InstallTortoiseOverlays();
		}

		private void RemoveOLReg_Click(object sender, EventArgs e)
		{
			RemoveOldEntriesX86();
		}

		private void RemoveOldEntriesX86()
		{
			bool found = false;
			string regPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\";
			string[] keys = new string[] {"_CheckedInWritableOverlay","_LizardAddOverlay","_LizardCheckedOutOverlay",
				"_LizardConflictOverlay","_LizardDeletedOverlay","_LizardDifferentOverlay","_LizardLockedOverlay",
				"_LizardNotCheckedOutOverlay","_LizardOutOfDateOverlay","_LizardReadonlyOverlay", "_UnknownStatusOverLay"};
			foreach (string key in keys)
			{
				string regKey = regPath + key;
				Microsoft.Win32.RegistryKey rkOldEntry = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regKey);
				if (rkOldEntry != null)
				{
					Microsoft.Win32.Registry.LocalMachine.DeleteSubKey(regKey);
					found = true;
				}
			}
			if (IsX64())
			{
				found |= RemoveOldEntriesx64();
			}
			if (found)
				MessageBox.Show("Old overlay entries have been removed.", "Remove Entries");
			else
				MessageBox.Show("No old entries were found.", "Remove Entries");


			ShowIntallationLabels();
		}

		private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			System.Diagnostics.Process.Start("http://tortoisesvn.tigris.org/");
		}


		private void ShowIntallationLabels()
		{
			bool installationComplete = true;

			string regPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\";
			string[] keys = new string[] {"_CheckedInWritableOverlay","_LizardAddOverlay","_LizardCheckedOutOverlay",
				"_LizardConflictOverlay","_LizardDeletedOverlay","_LizardDifferentOverlay","_LizardLockedOverlay",
				"_LizardNotCheckedOutOverlay","_LizardOutOfDateOverlay","_LizardReadonlyOverlay", "_UnknownStatusOverLay"};
			bool oldEntries = false;
			foreach (string key in keys)
			{
				try
				{
					string regKey = regPath + key;
					object rkOldEntry = Microsoft.Win32.Registry.GetValue(regKey, "", "");
					if (rkOldEntry != null)
					{
						oldEntries = true;
						break;
					}
				}
				catch { }
			}
			if (oldEntries)
			{
				lblOldEntries.ForeColor = Color.DeepPink;
				lblOldEntries.Text = "Old Entries Exist";
				installationComplete = false;
			}
			else
			{
				lblOldEntries.ForeColor = Color.DarkGreen;
				lblOldEntries.Text = "No Old Entries Exist";
			}

			bool isUpdateButton = false;
			if (IsX64())
			{
				isUpdateButton = TortoiseOverlaysX64Test();
				lblTortoiseOverlaysInstalled.Visible = isUpdateButton;
			}
			else
			{
				object rkTo = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\Software\\TortoiseOverlays", "", "");
				lblTortoiseOverlaysInstalled.Visible = (rkTo != null);
				installationComplete &= (rkTo != null);
				isUpdateButton = (rkTo != null);
			}
			btnUpdateOverlays.Enabled = isUpdateButton;

			if (!IsX64())
			{
				Microsoft.Win32.RegistryKey rkOverlays = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\TortoiseOverlays");
				string keyValue = rkOverlays.GetValue("UnversionedIcon", string.Empty).ToString();


				lblLizardIconsInstalled.Visible = keyValue.EndsWith("TortoiseOutOfDate.ico");

			}
			else
			{
				lblLizardIconsInstalled.Visible = CallX64RegistryApp("TestLizardOverlayValues");
			}

			object rkcurrentVersion = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\Software\\LizardTF", "Version", "");
			if (rkcurrentVersion == null || rkcurrentVersion.ToString() != lizardTFVersion)
			{
				lblLizardRegistered.ForeColor = Color.DeepPink;
				lblLizardRegistered.Text = "Lizard extensions are not registered";
				installationComplete = false;
			}
			else
			{
				lblLizardRegistered.ForeColor = Color.DarkGreen;
				lblLizardRegistered.Text = "Lizard extensions are registered";
			}
			if (!installationComplete)
			{
				foreach (TabPage tp in tabControl1.TabPages)
				{
					if (tp.Text == "Installation")
					{
						tabControl1.SelectedTab = tp;
						tp.Focus();
						break;
					}
				}
			}
		}

		private bool IsX64()
		{
			// a rather crude test to see if the OS is the 64bit version
			// this can easily be fooled, but there is no sense in fooling it!
			string winDir = System.Environment.GetEnvironmentVariable("windir");

			string wowDir = Path.Combine(winDir, "SysWOW64");

			return Directory.Exists(wowDir);
		}

		private bool RemoveOldEntriesx64()
		{
			return CallX64RegistryApp("RemoveOldOverlays");
		}


		private bool TortoiseOverlaysX64Test()
		{
			return CallX64RegistryApp("TestForTortoiseOverlays");
		}

		private static bool CallX64RegistryApp(string appCommand)
		{
			string asmFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);

			string cline = asmFolder + "\\LizardTFx64Registry.exe";

			Process p = new Process();

			ProcessStartInfo regSvr32 = new ProcessStartInfo(cline, appCommand);
			regSvr32.WindowStyle = ProcessWindowStyle.Hidden;
			regSvr32.UseShellExecute = true;
			p.StartInfo = regSvr32;

			p.Start();
			while (!p.HasExited)
			{
				System.Threading.Thread.Sleep(100);
			}
			return (p.ExitCode == 0);
		}

		private void button1_Click(object sender, EventArgs e)
		{
			this.WindowState = FormWindowState.Minimized;
		}

		private void btnStop_Click(object sender, EventArgs e)
		{
			this.Close();
		}


		private void btnUpdateOverlays_Click(object sender, EventArgs e)
		{
			if (IsX64())
			{
				CallX64RegistryApp("SetLizardOverlayValues");
			}
			else
			{
				string asmFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);

				string icons = asmFolder + "\\icons";

				Microsoft.Win32.RegistryKey rkOverlays = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\TortoiseOverlays", true);
				rkOverlays.SetValue("UnversionedIcon", icons + "\\TortoiseOutOfDate.ico");
				rkOverlays.SetValue("IgnoredIcon", icons + "\\TortoiseNoCheckOutDiff.ico");
			}
			ShowIntallationLabels();
		}

		private void explorerToolStripMenuItem_Click(object sender, EventArgs e)
		{
			LizardExplorer explorer = new LizardExplorer();
			explorer.Show();
		}

		private void chkForceThisServer_Clicked(object sender, EventArgs e)
		{
			Ltf.Remoting.Settings.TFSettings tfs = ServerConnections.DefaultConnection.Settings;

			if (chkForceThisServer.Checked)
			{
				tfs.ForcedServer = tfs.Server;
			}
			else
			{
				tfs.ForcedServer = null;
			}
		}

		private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (tabControl1.SelectedIndex == 0)
			{
				Ltf.Remoting.Settings.TFSettings tfs = ServerConnections.DefaultConnection.Settings;
				chkForceThisServer.Checked = (tfs.ForcedServer == tfs.Server);
			}

		}
	}
}